﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Controller_App
{
    /// <summary>
    /// Hauptform
    /// </summary>
    public partial class frm_main : Form
    {
        private System.Runtime.Remoting.Channels.Tcp.TcpClientChannel channel;
        private IVisual.I_Controller _ctrl;
        private string IP;

        public frm_main()
        {
            InitializeComponent();

            IVisual._SC.cls_LOG.LOG_LEVEL = IVisual._SC.cls_LOG.LOGLEVEL.ALL;
        }

        /// <summary>
        /// Stellt eine Verbindung zum Dienst her und initialisiert diese
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void frm_main_Load(object sender, EventArgs e)
        {
            try
            {
                IVisual._SC.frm_Connect _frm_con = new IVisual._SC.frm_Connect(!Environment.GetCommandLineArgs().Contains("-NOAD"));
                if (_frm_con.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                    CONNECT(_frm_con.IP.ToString(), _frm_con.Port);
                else
                    throw new Exception("Abbrechen geklickt");
            }
            catch (Exception)
            {
                this.Close();
                return;
            }

            this._t_refr.Enabled = true;
        }

        /// <summary>
        /// Stellt die Verbindung zu einer IP und Port her
        /// </summary>
        /// <param name="IP">Ziel-IP</param>
        /// <param name="port">Ziel-Port</param>
        private void CONNECT(string IP, long port)
        {
            channel = new System.Runtime.Remoting.Channels.Tcp.TcpClientChannel();
            System.Runtime.Remoting.Channels.ChannelServices.RegisterChannel(channel, true);

            _ctrl = (IVisual.I_Controller)Activator.GetObject
            (
                typeof(IVisual.I_Controller),
                "tcp://" + IP + ":" + port + "/_RM_Neuro_Controller"
            );

            this.IP = IP;
        }

        /// <summary>
        /// Schließt die Form
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void _cmd_close_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        /// <summary>
        /// Startet das Lernen
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void _cmd_start_learning_Click(object sender, EventArgs e)
        {
            this._cmd_start_learning.Visible = false;
            _ctrl.START_Learning();   
        }

        /// <summary>
        /// Beendet das Lernen
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void _cmd_stop_learning_Click(object sender, EventArgs e)
        {
            this._cmd_stop_learning.Visible = false;
            _ctrl.STOP_Learning();
        }

        /// <summary>
        /// Timer, welcher regelmäßig den Status des Dienst-thread abhohlt und die GUI switched
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void _t_refr_Tick(object sender, EventArgs e)
        {
            try
            {
                System.Threading.ThreadState _tmp = _ctrl.GET_STATE();

                this._l_status.Text = _tmp.ToString();

                if (_tmp == System.Threading.ThreadState.Stopped)
                {
                    this._cmd_start_learning.Visible = true;
                    this._cmd_stop_learning.Visible = false;
                }
                else
                {
                    this._cmd_start_learning.Visible = false;
                    this._cmd_stop_learning.Visible = true;

                    this._l_status.Text = "Fehler: " + Math.Round(_ctrl.GET_LAST_ERR(), 6);
                }

                this._cmd_query.Visible = this._cmd_start_learning.Visible;
                this._cmd_loadNet.Visible = this._cmd_start_learning.Visible;
                this._cmd_saveNet.Visible = this._cmd_start_learning.Visible;
                this._cmd_gew_edt.Visible = this._cmd_start_learning.Visible;
            }
            catch(Exception ex)
            {
                IVisual._SC.cls_LOG.WRITE_LOG_LINE(IVisual._SC.cls_LOG.LOGLEVEL.ERROR, ex.Message);

                this.Close();
            }
        }

        /// <summary>
        /// Handler für die Gewichtsänderung
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void _cmd_gew_edt_Click(object sender, EventArgs e)
        {
            if (_ctrl.GET_STATE() == System.Threading.ThreadState.Stopped)
            {
                frm_Gewicht_edit _edt = new frm_Gewicht_edit();
                _edt._ctrl = this._ctrl;

                _edt.ShowDialog();
            }
            else
            {
                MessageBox.Show("Es darf kein Lernvorgang ausgeführt werden um die Gewichte zu bearbeiten.");
            }
        }

        /// <summary>
        /// Handler für anfragen an das FERTIGE Netz
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void _cmd_query_Click(object sender, EventArgs e)
        {
            // Ausnahme für OCR ;-)
            if (_ctrl.GET_Mode() == "Zeichenerkennung")
            {
                frm_Zeichenerkennung_Query _tmp = new frm_Zeichenerkennung_Query();
                _tmp.INIT(this._ctrl);
                _tmp.ShowDialog();
            }
            else
            {
                frm_Query _tmp = new frm_Query();
                _tmp.INIT(_ctrl.GET_DIMENSION('I'), _ctrl.GET_DIMENSION('O'), this._ctrl);
                _tmp.ShowDialog();
            }
        }

        /// <summary>
        /// Veranlasst das Speichern des Netzen, mit Dialogen
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void _cmd_saveNet_Click(object sender, EventArgs e)
        {
            MessageBox.Show("Die Zieldatei muss vom Dienst aus schreibbar sein! Daher empfiehlt sich ein UNC-Pfad!");

            SaveFileDialog _sfd = new SaveFileDialog();
            _sfd.Filter = "Neuronale Netze|*.NN";
            _sfd.CheckPathExists = true;
            _sfd.InitialDirectory = "\\\\" + this.IP;
            _sfd.RestoreDirectory = false;
            _sfd.Title = "Bitte Speicherort auswählen.";
            if (_sfd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                _ctrl.SAVE_NET(_sfd.FileName, MessageBox.Show("Mit Konfiguration sichern?", "", MessageBoxButtons.YesNo) == System.Windows.Forms.DialogResult.Yes);
        }

        /// <summary>
        /// Veranlasst das Laden des Netzen, mit Dialogen
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void _cmd_loadNet_Click(object sender, EventArgs e)
        {
            MessageBox.Show("Die Zieldatei muss vom Dienst aus lesbar sein! Daher empfiehlt sich ein UNC-Pfad!");

            OpenFileDialog _ofd = new OpenFileDialog();
            _ofd.Filter = "Neuronale Netze|*.NN_NET";
            _ofd.CheckPathExists = true;
            _ofd.InitialDirectory = "\\\\" + this.IP;
            _ofd.RestoreDirectory = false;
            _ofd.Title = "Bitte Speicherort auswählen.";
            if (_ofd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                _ctrl.LOAD_NET(_ofd.FileName.Substring(0, _ofd.FileName.Length - 4));//_NET abschneiden
        }
    }
}
